<?php
/**
 * Created by PhpStorm.
 * User: wangjiangtao
 * Date: 2022/7/14
 * Time: 18:37
 */

namespace App\Modules\Popularize\Platform;


use App\Http\Model\AdvertiserCallbackLog;
use App\Http\Model\Device;
use App\Http\Model\Hint;
use App\Http\Model\MonitoringLink\AccessToken;
use App\Http\Model\MonitoringLink\HuaweiCallbackLogs;
use App\Http\Model\UserRegisterLog;
use App\Http\Services\AdvertiserCallbackLogServices;
use App\Http\Services\DeviceServices;

class PlatformOppo implements PlatformInterface
{

    protected $callback;
    protected $platform;
    protected $device;
    protected $userId;
    protected $adId;
    protected $oaid;
    protected $imei;

    protected $oppoUrl = 'https://api.ads.heytapmobi.com/api/uploadActiveData';
    protected $oppoSalt = 'e0u6fnlag06lc3pl';
    protected $oppoBase64Key = 'XGAXicVG5GMBsx5bueOe4w==';
    protected $oppoPkg = 'com.keke.lailaiadId';

    const ACTIVITE_EVENT = 1; //激活
    const REGISTER_EVENT = 2; //注册
    const PAY_EVENT = 7; //应用付费
    const PAY_NUMBERTIME_EVENT = 22; //应用付费次数

    public function __construct($callback, $platform, $device, $userId)
    {
        $this->platform = $platform;
        $this->device = $device;
        $this->userId = $userId;

        if (!empty($callback)) {
            //从url中截取信息
            $uri = parse_url($callback);
            parse_str($uri['query'], $results);
            $this->adId = $results['advertiser_id'] ?? "";
            $this->oaid = $results['oaid'] ?? "";
            $this->imei = $results['imei'] ?? "";
            $dm = explode('?', $callback);
            $this->callback = $dm[0] ?? "";
        }
    }

    public function active(): ?bool
    {
        $requestData = $this->_buildRequestData(self::ACTIVITE_EVENT);
        if (empty($requestData)) {
            return false;
        }
        $params = json_decode(json_encode($this->device), true);
        $params = $this->_checkField($params);
        try {
            if (isset($this->device->guid) && $this->device->guid != '') {
                //查询是否存在设备信息，如果存在就说明设备已经激活
                $deviceModel = new Device();
                $deviceInfo = $deviceModel->getByGuid($this->device->guid);
                if (!empty($deviceInfo)) {
                    write_log('Platform', 'platform_oppo', ["设备已存在", $params]);
                    return false;
                }
                $deviceModel->save($params);
                //获取用户注册并修改渠道
                $model = new UserRegisterLog();
                $userRegisterLog = $model->findRecordByGuid($this->device->guid, ['user_id']);
                if ($userRegisterLog && $this->platform != '' && is_numeric($userRegisterLog['platform']) && $userRegisterLog['platform'] == $userRegisterLog['channel_id']) {
                    $model->updatePlatform($userRegisterLog['user_id'], $this->platform);
                }
                write_log('Platform', 'platform_oppo', ["保存设备信息成功", $params]);
                return $this->_report(self::ACTIVITE_EVENT, $requestData);
            }

        } catch (\Exception $e) {
            write_log('Platform', 'platform_oppo', ["保存设备信息失败", $params, $e->getMessage()]);
            return false;
        }
        return false;
    }

    public function regist(): ?bool
    {
        $requestData = $this->_buildRequestData(self::REGISTER_EVENT);
        if (empty($requestData)) {
            return false;
        }
        return $this->_report(self::REGISTER_EVENT, $requestData);
    }

    public function pay($amount = 0): ?bool
    {
        //应用付费
        $requestData = $this->_buildRequestData(self::PAY_EVENT, $amount);
        if (empty($requestData)) {
            return false;
        }
        $this->_report(self::PAY_EVENT, $requestData);

        //应用付费次数
        $requestData = $this->_buildRequestData(self::PAY_NUMBERTIME_EVENT);
        if (empty($requestData)) {
            return false;
        }
        $this->_report(self::PAY_NUMBERTIME_EVENT, $requestData);

        return true;
    }

    /**
     * 获取设备信息
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|object|void|null
     */
    public function getDevice()
    {
        return $this->device;
    }

    private function _buildRequestData($type, $payAmount = 0)
    {
        $requestData = [];

        if (empty($this->oaid) && empty($this->imei)) {
            return null;
        }
        if (!empty($this->oaid)) {
            $requestData['ouId'] = $this->_encrypt($this->oaid, $this->oppoBase64Key);
            $requestData['type'] = 0;
        } else {
            $requestData['imei'] = $this->_encrypt($this->imei, $this->oppoBase64Key);
            $requestData['type'] = 1;
        }

        if ($type == self::PAY_EVENT) {
            $requestData['payAmount'] = $payAmount ? intval($payAmount * 100) : '';
        }

        $requestData['appType'] = 1; //应用
        $requestData['clientIp'] = client_ip();
        $requestData['dataType'] = $type;
        $requestData['ascribeType'] = 1;
        $requestData['adId'] = $this->adId; //广告主归因id
        $requestData['timestamp'] = $this->_getMsecTime();
        $requestData['pkg'] = $this->oppoPkg;         //包名，
        $requestData['channel'] = 1;                   //1、OPPO，2、一加，0、其他

        return $requestData;
    }

    //上报oppo
    private function _report($type, $requestData)
    {
        if (empty($requestData)) {
            return false;
        }
        try {
            $header = $this->_setHeader($requestData);
            $res = curlRequest($this->callback, $requestData, true, $header, 10, true);
            write_log('Advertisement', 'platform_oppo_success', [$type, $this->callback, $requestData, $res]);
        } catch (\Exception $exception) {
            write_log('Advertisement', 'platform_oppo_error', [$type, $this->callback, $requestData, $exception->getMessage()]);
            return false;
        }
        $result = json_decode($res);
        return isset($result->code) && $result->code == 0;

    }

    protected function _checkField($params = [])
    {
        do {
            $checkField = ['cid', 'aid', 'callback', 'advertiser_id', 'guid', 'idfa', 'version_no', 'os_name', 'device', 'channel_id', 'platform', 'imei', 'oaid', 'adid', 'conv_ext', 'client_ip'];
            if (empty($params)) {
                break;
            }

            $inputParams = [];
            foreach ($checkField as $field) {
                if (array_key_exists($field, $params)) {
                    $inputParams[$field] = $params[$field];
                }
            }

            $params = $inputParams;
        } while (false);

        return $params;
    }

    private function _setHeader($postData)
    {
        $data = [];
        $time = (string)$this->_getMsecTime();
        //生成签名
        $data[] = 'signature:' . $this->_createSign($postData, $time, $this->oppoSalt);
        $data[] = 'timestamp:' . $time;
        $data[] = 'Content-Type:application/json';

        return $data;
    }

    private function _createSign($postData, $time, $salt)
    {
        $data = json_encode($postData) . $time . $salt;
        return md5($data);
    }

    /**
     * imei 与 mac 字段 AES 算法进行加密
     * @param $input
     * @param $base64Key
     * @return false|string
     */
    private function _encrypt($input, $base64Key)
    {
        return openssl_encrypt($input, 'AES-128-ECB', base64_decode($base64Key), 0, '');
    }

    /**
     * 获取毫秒级别的时间戳
     */
    private function _getMsecTime()
    {
        list($msec, $sec) = explode(' ', microtime());
        $msectime = (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
        return $msectime;
    }

}
